package cn.xeblog.plugin.game.chess2;

import cn.xeblog.commons.entity.User;
import cn.xeblog.commons.entity.game.chess.ChessDTO;
import cn.xeblog.commons.enums.Game;
import cn.xeblog.plugin.annotation.DoGame;
import cn.xeblog.plugin.cache.DataCache;
import cn.xeblog.plugin.game.AbstractGame;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;

import static cn.xeblog.plugin.game.chess2.ChessConstant.BLACKPLAYSIGN;
import static cn.xeblog.plugin.game.chess2.ChessConstant.REDPLAYSIGN;

/**
 * 中国象棋入口
 * 作者：Hao.<br>
 */
@DoGame(Game.CHINESE_CHESS2)
public class ChineseChess extends AbstractGame<ChessDTO> {
    /**
     * 行的数量
     */
    public static final int NUM_ROWS = 10;
    /**
     * 列的数量
     */
    public static final int NUM_COLS = 9;
    /**
     * 开始界面
     */
    private JPanel startPanel;

    /**
     * 游戏界面
     */
    private ChessBoardMain gamePanel;

    // ----------------  开始界面 组件  ----------------
    /**
     * 对战方式
     */
    private JComboBox<String> jcb_fightType;
    /**
     * 玩家所属阵营列表（红方、黑方）
     */
    private JComboBox<String> jcb_playFirst;
    /**
     * 玩家界面类型
     */
    private JComboBox<String> jcb_UIType;
    /**
     * 中国象棋缓存
     */
    public ChessCache chessCache;

    public static GameCache gameCache;
    /**
     * 游戏状态 -2.初始化 -1.待开始 0.进行中 1.赢 2.平
     */
    int status = -2;

    private static ComputerLevel computerLevel = ComputerLevel.greenHand; //默认

    @Override
    protected void start() {
        // 在线模式-游戏开始
        startGame0(ChessCache.Mode.ONLINE, false, false);
    }

    @Override
    protected void init() {
        this.gameCache = GameCache.getInstance();
        // 启用主界面并设置可见、最小尺寸
        super.mainPanel.removeAll();
        super.mainPanel.setLayout(null);
        super.mainPanel.setEnabled(true);
        super.mainPanel.setVisible(true);
        super.mainPanel.setMinimumSize(new Dimension(230, 400));

        // 开始面板设置
        this.startPanel = new JPanel();
        this.startPanel.setBounds(10, 10, 200, 400);


        // 构建开始面板
        this.startPanel();

        // 刷新界面
        super.mainPanel.add(this.startPanel);
        super.mainPanel.updateUI();
    }

    @Override
    protected void allPlayersGameStarted() {
        // 当前所属阵营
        boolean currentPlayer = !chessCache.currentPlayer;
        // 对方所属阵营
        boolean opposingPlayer = !currentPlayer;

        // 当前界面
        ChessDTO.UI currentUI = ChessDTO.UI.CLASSIC;
        // 房主
        if (isHomeowner()) {
            // 自旋等待一段时间，再发送游戏数据
            invoke(() -> {
                ChessDTO msg = new ChessDTO();
                msg.setType(opposingPlayer);
                msg.setCurrentUI(currentUI);
                sendMsg(msg);
                handle(new ChessDTO(0, 0, currentPlayer, -1, ChessDTO.Option.DEFAULT, currentUI));
            }, 500);
        }
    }

    @Override
    public void handle(ChessDTO body) {
        if (status > -1) {
//            // 对方悔棋
//            if (body.getOption().equals(ChessDTO.Option.UNDO)) {
//                gamePanel.otherSideUndo();
//                return;
//            }
//            // 游戏结束，对方投降
//            if (body.getOption().equals(ChessDTO.Option.SURRENDER)) {
//                JOptionPane.showMessageDialog(null, "对方投降了！");
//                gamePanel.gameOver();
//                return;
//            }
//            // 游戏结束
//            if (body.getOption().equals(ChessDTO.Option.GAME_OVER)) {
//                JOptionPane.showMessageDialog(null, "胜败乃兵家常事，少侠请重新来过！");
//                gamePanel.gameOver();
//                return;
//            }
//
//            // 另一方检查，即”将军“
//            if (body.getOption().equals(ChessDTO.Option.CHECK)) {
//                gamePanel.otherSideCheck();
//            }
//
//            // 改变玩家信息
//            changePlayer(body);
//            // 设置棋子
//            gamePanel.setChess(new Point(body.getX(), body.getY(), body.getType(), body.getIndex()));
//
//            // 游戏结束，跳出
//            if (gamePanel.isGameOver) {
//                return;
//            }
        } else {
            // 状态变为进行中，在线人人对战，同时红方状态文本改为“思考中”
            status = 0;
            chessCache.currentMode = ChessCache.Mode.ONLINE;
            chessCache.currentBattle = ChessCache.Battle.PVP;
            chessCache.currentUI = body.getCurrentUI();
//            this.gamePanel.redStateTextLabel.setText("思考中");

            // 黑方初始化棋盘,变更当前玩家阵营且已落子
            if (!body.isType()) {
                chessCache.currentPlayer = body.isType();
                gamePanel.initHandler();
                chessCache.put = true;
                return;
            } else {
                // 设置当前玩家为红方
                chessCache.currentPlayer = true;
            }
        }

//        // 如果可以悔棋，则启用悔棋按钮
//        if (gamePanel.canRepent()) {
//            this.gamePanel.undoBtn.setEnabled(true);
//        }

        // 当前未落子
        chessCache.put = false;
    }

    /**
     * 开始游戏
     *
     * @param mode 在线/离线模式
     * @return void
     * @author Hao.
     * @date 2022/9/5 10:09
     */
    private void startGame0(ChessCache.Mode mode, boolean isRedAI, boolean isBlackAI) {
        // 构建主窗口大小
        super.mainPanel.removeAll();
        super.mainPanel.revalidate();
        super.mainPanel.repaint();
        super.mainPanel.setLayout(new BorderLayout());
        super.mainPanel.setMinimumSize(new Dimension(320, 450));

        // 添加游戏面板
        this.gamePanel = new ChessBoardMain(this);
        super.mainPanel.add(gamePanel, BorderLayout.CENTER);
        gamePanel.setRed(true);

        if (isBlackAI) {
            gamePanel.isBlackAi();
            gamePanel.computerLevel = computerLevel;
        } else {
            gamePanel.play = BLACKPLAYSIGN;
            gamePanel.android[BLACKPLAYSIGN] = false;
            gamePanel.setRed(false);
        }

        if (isRedAI) {
            gamePanel.isRedAi();
            gamePanel.computerLevel = computerLevel;
        } else {
            gamePanel.play = REDPLAYSIGN;
            gamePanel.android[REDPLAYSIGN] = false;
            gamePanel.setRed(true);
        }

//        // 离线模式时
//        if (mode == ChessCache.Mode.OFFLINE) {
//            // 未落子，且无限悔梅
//            chessCache.put = false;
//            gamePanel.redUndoNum = 999;
//            gamePanel.blackUndoNum = 999;
//            this.gamePanel.blackUndoTextLabel.setText("剩" + gamePanel.blackUndoNum + "次");
//            this.gamePanel.redUndoTextLabel.setText("剩" + gamePanel.redUndoNum + "次");
//            gamePanel.remove(gamePanel.surrenderBtn);
//            // 添加离开按钮
//            gamePanel.add(gamePanel.exitButton());
//        }

        // 刷新界面
        super.mainPanel.updateUI();
    }

//    /**
//     * 发送点位
//     *
//     * @param point 点位
//     */
//    public void send(Point point) {
//        ChessDTO dto = new ChessDTO();
//        dto.setX(point.x);
//        dto.setY(point.y);
//        dto.setType(point.type);
//        dto.setIndex(point.index);
//        dto.setOption(point.option);
//        sendMsg(dto);
//    }

    /**
     * 右边功能区布局<br>
     */
    private void startPanel() {

        Box vBox = Box.createVerticalBox();

        ImageIcon imageIconLogo = new ImageIcon(new ImageIcon(this.getClass().getResource("/games/chinese-chess/logo.png")).getImage().getScaledInstance(100, 50, Image.SCALE_SMOOTH));//缩放图片来适应标签大小
        JLabel labelLogo = new JLabel(imageIconLogo);

        vBox.add(Box.createVerticalStrut(20));
        Box logo = Box.createHorizontalBox();
        logo.add(Box.createHorizontalGlue());
        logo.add(Box.createHorizontalGlue());
        logo.add(labelLogo);
        logo.add(Box.createHorizontalGlue());
        vBox.add(logo);

        // 红方人类/AI单选框，默认选中人类
        JLabel redHeader = GuiUtil.getGeneral("红方玩家:");
        JRadioButton redHumanButton = new JRadioButton(GameCache.HUMAN_TEXT);
        JRadioButton redAIButton = new JRadioButton(GameCache.AI_TEXT);

        // 加入按钮组
        ButtonGroup redGroup = new ButtonGroup();
        redGroup.add(redHumanButton);
        redGroup.add(redAIButton);
        redHumanButton.setSelected(true);


        vBox.add(Box.createVerticalStrut(20));

        Box red = Box.createHorizontalBox();
        red.add(redHeader);
        red.add(Box.createHorizontalStrut(5));
        red.add(redHumanButton);
        red.add(Box.createHorizontalStrut(5));
        red.add(redAIButton);
        vBox.add(red);

        vBox.add(Box.createVerticalStrut(10));

        // 黑方人类/AI单选框，默认选中人类
        JLabel blackHeader = GuiUtil.getGeneral("黑方玩家:");
        JRadioButton blackHumanButton = new JRadioButton(GameCache.HUMAN_TEXT);
        JRadioButton blackAIButton = new JRadioButton(GameCache.AI_TEXT);
        // 加入按钮组
        ButtonGroup blackGroup = new ButtonGroup();
        blackGroup.add(blackHumanButton);
        blackGroup.add(blackAIButton);
        blackHumanButton.setSelected(true);


        // 加入节点

        Box black = Box.createHorizontalBox();
        black.add(blackHeader);
        black.add(Box.createHorizontalStrut(5));
        black.add(blackHumanButton);
        black.add(Box.createHorizontalStrut(5));
        black.add(blackAIButton);
        vBox.add(black);

        //  AI 设置
        JLabel AIText = GuiUtil.getGeneral("电脑级别:");
        // AI难度级别
        JComboBox chessAIBox = new JComboBox();
        chessAIBox.addItem("菜鸟");
        chessAIBox.addItem("入门");
        chessAIBox.addItem("业余");
        chessAIBox.addItem("专业");
        chessAIBox.addItem("大师");
        chessAIBox.addItem("无敌");
        chessAIBox.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.SELECTED == e.getStateChange()) {
                    //getSelectedItem()返回当前所选项
                    //getSelectedIndex()返回列表中与给定项匹配的第一个选项。
                    Object item = e.getItem();
                    if ("菜鸟".equals(item)) {
                        computerLevel = ComputerLevel.greenHand;
                    } else if ("入门".equals(item)) {
                        computerLevel = ComputerLevel.introduction;
                    } else if ("业余".equals(item)) {
                        computerLevel = ComputerLevel.amateur;
                    } else if ("专家".equals(item)) {
                        computerLevel = ComputerLevel.career;
                    } else if ("大师".equals(item)) {
                        computerLevel = ComputerLevel.master;
                    } else if ("无敌".equals(item)) {
                        computerLevel = ComputerLevel.invincible;

                    }
                }
            }
        });

        vBox.add(Box.createVerticalStrut(10));
        Box ai = Box.createHorizontalBox();
        ai.add(AIText);
        ai.add(Box.createHorizontalStrut(5));
        ai.add(chessAIBox);
        ai.add(Box.createHorizontalGlue());
        vBox.add(ai);


        vBox.add(Box.createVerticalStrut(40));


        // 开始游戏按钮
        JButton startGameButton = new JButton("开始游戏");
        startGameButton.addActionListener(e -> {
            startGame0(ChessCache.Mode.OFFLINE, redAIButton.isSelected(), blackAIButton.isSelected());
        });

        Box startGameBox = Box.createHorizontalBox();
        startGameBox.add(Box.createHorizontalGlue());
        startGameBox.add(Box.createHorizontalGlue());
        startGameBox.add(startGameButton);
        startGameBox.add(Box.createHorizontalGlue());
        vBox.add(startGameBox);

        // 在线显示创建房间按钮
        if (DataCache.isOnline) {
            // 如果已经是登录状态，就显示创建房间按钮
            // 如果已经是登录状态，就显示创建房间按钮
            List<Integer> numsList = new ArrayList<>();
            numsList.add(2);

            Box createRoomBox = Box.createHorizontalBox();
            createRoomBox.add(Box.createHorizontalGlue());
            createRoomBox.add(Box.createHorizontalGlue());
            createRoomBox.add(getCreateRoomButton(numsList));
            createRoomBox.add(Box.createHorizontalGlue());
            vBox.add(createRoomBox);
        }

        // 退出按钮
        Box exitBox = Box.createHorizontalBox();
        exitBox.add(Box.createHorizontalGlue());
        exitBox.add(Box.createHorizontalGlue());
        exitBox.add(

                getExitButton());
        exitBox.add(Box.createHorizontalGlue());
        vBox.add(exitBox);

        startPanel.add(vBox);
    }


    /**
     * 改变玩家信息
     *
     * @param body 消息体
     */
    private void changePlayer(ChessDTO body) {
        // 棋子信息对调
        body.setX(9 - body.getX());
        body.setY(8 - body.getY());

//        // 变更玩家状态信息
//        if (body.getType() == ChessCache.Player.BLACK.getValue()) {
//            this.gamePanel.redStateTextLabel.setText("思考中");
//            this.gamePanel.blackStateTextLabel.setText("已下完");
//        } else {
//            this.gamePanel.redStateTextLabel.setText("已下完");
//            this.gamePanel.blackStateTextLabel.setText("思考中");
//        }
    }

    /**
     * 游戏结束按钮
     *
     * @return 游戏结束按钮
     */
    public JButton gameOverButton() {
        // 游戏结束按钮
        return getGameOverButton();
    }

    /**
     * 返回上一页按钮
     *
     * @return 返回上一页按钮
     */
    public JButton getPrePageButton() {
        // 游戏结束按钮
        return super.getPrePageButton();
    }

//    /**
//     * 设置退出按钮，并绑定结果命令
//     *
//     * @return 按钮组件
//     */
//    protected JButton getStartGameButton() {
//        JButton startGameButton = new JButton("开始游戏");
//        // 离线对弈
//        startGameButton.addActionListener(e -> {
//            this.startGame0(ChessCache.Mode.OFFLINE);
//        });
//        return startGameButton;
//    }


    @Override
    public void playerLeft(User player) {
        // 玩家离开
        super.playerLeft(player);
        // 游戏未结束且状态已开始时，离开即投降
//        if (!gamePanel.isGameOver && status > -1) {
//            ChessDTO dto = new ChessDTO();
//            dto.setOption(ChessDTO.Option.SURRENDER);
//            handle(dto);
//        }
    }


}
